package com.bodu.service.impl;

import com.bodu.entity.InfomationColumnEntity;
import com.bodu.entity.TemplateEntity;
import com.bodu.enums.GenFileSuffixEnum;
import com.bodu.enums.GenFileTypeEnum;
import com.bodu.mapper.CommonMapper;
import com.bodu.service.GenCodeService;
import com.bodu.util.ObjectTransitionUtils;
import com.bodu.util.TemplateContentUtils;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author Administrator
 */
@Slf4j
@Service("genCodeService")
public class GenCodeServiceImpl implements GenCodeService {

    @Autowired
    private CommonMapper commonMapper;

    @Autowired
    private TemplateEntity templateEntity;

    @Autowired
    public Template controllerTemplate;

    @Autowired
    public Template serviceTemplate;

    @Autowired
    public Template serviceImplTemplate;

    @Autowired
    public Template daoTemplate;

    @Autowired
    public Template daoXmlTemplate;

    /**
     * 生成所有的代码文件
     *
     * @param table 传入表名称
     * @param type  文件类型
     * @return
     */
    @Override
    public void createAll(String schema, String table, Integer type) {
        if (Objects.equals(GenFileTypeEnum.ALL.getKey(), type)
                || Objects.equals(GenFileTypeEnum.CONTROLLER, type)) {
            createController(schema, table);
        }

        if (Objects.equals(GenFileTypeEnum.ALL.getKey(), type)
                || Objects.equals(GenFileTypeEnum.SERVICE, type)) {
            createService(schema, table);
        }

        if (Objects.equals(GenFileTypeEnum.ALL.getKey(), type)
                || Objects.equals(GenFileTypeEnum.SERVICE_IMPL, type)) {
            createServiceImpl(schema, table);
        }

        if (Objects.equals(GenFileTypeEnum.ALL.getKey(), type)
                || Objects.equals(GenFileTypeEnum.DAO, type)) {
            createDao(schema, table);
        }

        if (Objects.equals(GenFileTypeEnum.ALL.getKey(), type)
                || Objects.equals(GenFileTypeEnum.DAO_XML, type)) {
            createDaoXml(schema, table);
        }
    }

    private boolean createController(String schema, String table) {
        return createFile(schema, table, controllerTemplate, fileSavePath(table, GenFileSuffixEnum.CONTROLLER.getSuffix()));
    }

    private boolean createService(String schema, String table) {
        return createFile(schema, table, serviceTemplate, fileSavePath(table, GenFileSuffixEnum.SERVICE.getSuffix()));
    }

    private boolean createServiceImpl(String schema, String table) {
        return createFile(schema, table, serviceImplTemplate, fileSavePath(table, GenFileSuffixEnum.SERVICE_IMPL.getSuffix()));
    }

    private boolean createDao(String schema, String table) {
        return createFile(schema, table, daoTemplate, fileSavePath(table, GenFileSuffixEnum.DAO.getSuffix()));
    }

    private boolean createDaoXml(String schema, String table) {
        return createFile(schema, table, daoXmlTemplate, fileSavePath(table, GenFileSuffixEnum.DAO_XML.getSuffix()));
    }

    /**
     * 生成的文件路径
     *
     * @param table      数据表名称
     * @param fileSuffix 文件后缀
     * @return java.lang.String
     */
    private String fileSavePath(String table, String fileSuffix) {
        String controllerName = ObjectTransitionUtils.captionLine(table);
        return templateEntity.getDaoXmlFilePath() + "/" + controllerName + fileSuffix;
    }

    /**
     * 生成代码文件
     *
     * @param table    表的名称
     * @param descFile 目标文件的 （绝对地址）
     * @return 返回成功或失败 true -> 成功 ， false -> 失败
     */
    private boolean createFile(String schema, String table, Template template, String descFile) {
        boolean createSuccess = true;
        try {
            List<InfomationColumnEntity> infomationColumnEntities = commonMapper.findMysqlInfomationColumns(schema, table);
            PrintStream printStream = new PrintStream(descFile);
            Writer out = new OutputStreamWriter(printStream);
            Map<String, Object> root = getMapData(table, templateEntity, infomationColumnEntities);
            template.process(root, out);
            out.close();
            printStream.close();
        } catch (Exception e) {
            e.printStackTrace();
            createSuccess = false;
        }
        return createSuccess;
    }

    /**
     * 设置数据参数
     */
    public Map<String, Object> getMapData(String table, TemplateEntity templateEntity, List<InfomationColumnEntity> infomationColumnEntities) {
        Map<String, Object> map = new HashMap<>(16);
        map.put("content", TemplateContentUtils.createTemplateContent(templateEntity, infomationColumnEntities, table));
        return map;
    }
}
